﻿/********************************************************************************/
// <copyright file="RepositoryBase.cs" company="Asia E-Business Solutions">
//     Copyright © 2012. All right reserved
// </copyright>
//
// <history>
//  <change who="Hieu Nguyen" date="11/12/2012 12:12:09 PM">Created</change>
// <history>
/********************************************************************************/
namespace JLL.China.Infrastructure.RepositoryFramework
{
    using System.Collections.Generic;
    using JLL.China.Infrastructure.DomainBase;
    using JLL.China.Infrastructure.UnitOfWork;

    public abstract class RepositoryBase<E, T> : IRepository<E, T>, IUnitOfWorkRepository<T>
        where E : IAggregateRoot<T>
        where T : new()
    {
        #region -- Private Fields --

        private IUnitOfWork<T> unitOfWork;

        #endregion

        #region -- Constructors --

        protected RepositoryBase()
            : this(null)
        {
        }

        protected RepositoryBase(IUnitOfWork<T> unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        #endregion

        #region -- IRepository<T> Members --

        public abstract E FindBy(T key);

        public abstract IList<E> FindAll();

        public void SetUnitOfWork(IUnitOfWork<T> unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        public void Add(E item)
        {
            if (this.unitOfWork != null)
            {
                this.unitOfWork.RegisterAdded(item, this);
            }
        }

        public void Remove(E item)
        {
            if (this.unitOfWork != null)
            {
                this.unitOfWork.RegisterRemoved(item, this);
            }
        }

        public E this[T key]
        {
            get
            {
                return this.FindBy(key);
            }
            set
            {
                if (this.FindBy(key) == null)
                {
                    this.Add((E)value);
                }
                else
                {
                    if (this.unitOfWork != null)
                    {
                        this.unitOfWork.RegisterChanged((E)value, this);
                    }
                }
            }
        }

        #endregion

        #region -- IUnitOfWorkRepository Members --

        public virtual void PersistNewItem(IEntity<T> item)
        {
            this.PersistNewItem((E)item);
        }

        public virtual void PersistUpdatedItem(IEntity<T> item)
        {
            this.PersistUpdatedItem((E)item);
        }

        public virtual void PersistDeletedItem(IEntity<T> item)
        {
            this.PersistDeletedItem((E)item);
        }

        #endregion

        #region -- Properties --

        public IUnitOfWork<T> UnitOfWork
        {
            get { return this.unitOfWork; }
        }

        #endregion

        #region -- Abstract Methods --

        protected abstract void PersistNewItem(E item);
        protected abstract void PersistUpdatedItem(E item);
        protected abstract void PersistDeletedItem(E item);

        #endregion
    }
}
